'''oto/gtk/dialogs.py

This module contains the GTK dialogs used in Oranges to Oranges.
'''

__author__ = 'Ryan Rousseau <ryan.rousseau@gmail.com>'
__license__ = '''Oranges to Oranges
Copyright (C) 2006  Ryan Rousseau

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
'''

# PyGTK imports

import pygtk
pygtk.require('2.0')
import gtk
import gobject

__all__ = ['SelectGameDialog', 'NewGameDialog', 'ConnectToSiteDialog']

# Dialog #

class Dialog(gtk.Dialog):
    '''Dialog(title, [buttons])

Custom GTK Dialog.
'''
    def __init__(self, title, buttons=None):
        if not buttons:
            buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                       gtk.STOCK_OK, gtk.RESPONSE_OK)
        kwords = {
            'title': title,
            'buttons': buttons,
        }
        gtk.Dialog.__init__(self, **kwords)

# ErrorDialog #

class ErrorDialog(Dialog):
    '''ErrorDialog(message)

An Error Dialog for Oto.
message is the error message to display.
'''
    def __init__(self, message):
        buttons = (gtk.STOCK_OK, gtk.RESPONSE_OK)
        Dialog.__init__(self, 'An Error Has Occurred', buttons)
        icon = self.render_icon(gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_DIALOG)
        self.set_icon(icon)
        hbox = gtk.HBox()
        image = gtk.Image()
        image.set_from_stock(gtk.STOCK_DIALOG_ERROR, gtk.ICON_SIZE_DIALOG)
        hbox.pack_start(image, False, False, 1)
        hbox.pack_start(gtk.Label(message), False, False, 1)
        self.vbox.pack_start(hbox, False, False, 1)
        self.set_urgency_hint(True)
        self.show_all()

# WarningDialog #

class WarningDialog(Dialog):
    '''WarningDialog(message)

An Warning Dialog for Oto.
message is the warning message to display.
'''
    def __init__(self, message):
        buttons = (gtk.STOCK_OK, gtk.RESPONSE_OK)
        Dialog.__init__(self, 'Warning', buttons)
        icon = self.render_icon(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
        self.set_icon(icon)
        hbox = gtk.HBox()
        image = gtk.Image()
        image.set_from_stock(gtk.STOCK_DIALOG_WARNING, gtk.ICON_SIZE_DIALOG)
        hbox.pack_start(image, False, False, 1)
        hbox.pack_start(gtk.Label(message), False, False, 1)
        self.vbox.pack_start(hbox, False, False, 1)
        self.set_urgency_hint(True)
        self.show_all()

# MessageDialog #

class MessageDialog(Dialog):
    '''MessageDialog(message)

Display a message to the user in a dialog.
'''
    def __init__(self, title, message):
        buttons = (gtk.STOCK_OK, gtk.RESPONSE_OK)
        Dialog.__init__(self, title, buttons)
        self.vbox.pack_start(Label(message), False, False, 1)
        self.show_all()

# NewGameDialog #

class NewGameDialog(Dialog):
    '''NewGameDialog()

Oto GTK Dialog for creating a new hosted game.
'''
    def __init__(self):
        def on_entry_activate(entry):
            button = self.action_area.get_children()[0]
            button.clicked()
    
        ### on_name_entry_changed ###
        def on_name_entry_changed(entry):
            '''on_name_entry_changed(entry)

Callback for when the name entry is changed.
'''
            text = ''
            name = entry.get_text()
            if '' == name:
                text += 'Game name cannot be blank.\n'
            if 'identifier' == name.lower():
                text += 'Game name cannot be "identifier".\n'
            if -1 != name.find(' '):
                text += 'Game name cannot contain spaces.\n'
            if -1 != name.find('\\'):
                text += 'Game name cannot contain backslashes.\n'
            if -1 != name.find(':'):
                text += 'Game name cannot contain colons.\n'
            if -1 != name.find('.'):
                text += 'Game name cannot contain periods.\n'
            if -1 != name.find('_'):
                text += 'Game name cannot contain underscores.\n'
            text = text.strip()
            self.error_label.set_text(text)
            if '' == text:
                self.action_area.get_children()[0].set_sensitive(True)
            else:
                self.action_area.get_children()[0].set_sensitive(False)

        # create the dialog
        
        Dialog.__init__(self, 'Create a Hosted Game')
        hbox = gtk.HBox(False, 1)
        label_box = gtk.VBox(True, 1)
        other_box = gtk.VBox(True, 1)
        # name entry
        label_box.pack_start(gtk.Label('Game Name: '), False, False, 1)
        self.name_entry = gtk.Entry()
        self.name_entry.connect('activate', on_entry_activate)
        other_box.pack_start(self.name_entry, True, True, 1)
        hbox.pack_start(label_box, False, False, 1)
        hbox.pack_start(other_box, True, True, 1)
        self.vbox.pack_start(hbox, False, False, 1)
        self.error_label = gtk.Label()
        self.vbox.pack_start(self.error_label, False, False, 1)
        self.name_entry.connect('changed', on_name_entry_changed, session_names)
        self.name_entry.set_text('my_game')
        self.show_all()


    ## get_game_name ##

    def get_game_name(self):
        '''get_game_name()

Return the session name.
'''
        return self.name_entry.get_text()

# ConnectToSiteDialog #

class ConnectToSiteDialog(Dialog):
    '''ConnectToSiteDialog(sites)

A GTK Dialog used to connect to an Oto Site.
sites is a dict of site names/hosts.
'''
    def __init__(self, sites):
        def on_entry_activate(entry):
            button = self.action_area.get_children()[0]
            button.clicked()
            
        ### on_site_combo_box_changed ###
        
        def on_site_combo_box_changed(combo_box, sites):
            '''on_site_combo_box_changed(combo_box, sites)

Callback for when the session combo box is changed.
'''
            site = combo_box.get_active_text()
            if site in sites:
                self.name_entry.set_text(site)
                self.host_entry.set_text(sites[site])
            else:
                self.name_entry.set_text('')
                self.host_entry.set_text('')

        Dialog.__init__(self, 'Connect to an Oto Site')
        
        hbox = gtk.HBox(False, 1)
        label_box = gtk.VBox(True, 1)
        other_box = gtk.VBox(True, 1) # combo boxes and 2 entries
        label_box.pack_start(gtk.Label('Site: '), False, False, 1)
        self.site_combo_box = gtk.combo_box_new_text()
        other_box.pack_start(self.site_combo_box, True, True, 1)
        label_box.pack_start(gtk.Label('Name: '), False, False, 1)
        self.name_entry = gtk.Entry()
        self.name_entry.connect('activate', on_entry_activate)
        other_box.pack_start(self.name_entry, True, True, 1)
        label_box.pack_start(gtk.Label('Host: '), False, False, 1)
        self.host_entry = gtk.Entry()
        self.host_entry.connect('activate', on_entry_activate)
        other_box.pack_start(self.host_entry, True, True, 1)
        hbox.pack_start(label_box, True, True, 1)
        hbox.pack_start(other_box, True, True, 1)
        self.vbox.pack_start(hbox, False, False, 1)
        self.check_button = gtk.CheckButton('Connect to this site on start')
        self.vbox.pack_start(self.check_button, False, False, 1)

        site_names = sites.keys()
        site_names.sort()
        for site in site_names:
            self.site_combo_box.append_text(site)
            
        self.site_combo_box.connect('changed',
                                       on_site_combo_box_changed, sites)
        self.site_combo_box.set_active(0)
        self.show_all()

    def get_name(self):
        return self.name_entry.get_text()

    def get_host(self):
        return self.host_entry.get_text()

    def get_autoconnect(self):
        return self.check_button.get_active()

# ConnectToGameDialog #

class ConnectToGameDialog(Dialog):
    '''ConnectToGameDialog(games)

A GTK Dialog used to connect to a Oto game.
games is a list of game names.
'''
    def __init__(self, sessions):        
        ### on_game_combo_box_changed ###
        def on_game_combo_box_changed(combo_box):
            '''on_session_combo_box_changed(combo_box)

Callback for when the session combo box is changed.
'''
            game = combo_box.get_active_text()
            self.name_combo_box.get_model().clear()
            #students = self.games[game]
            #students.sort()
            #for name in students:
            #    self.name_combo_box.append_text(name)
            self.name_combo_box.show_all()
            self.name_combo_box.set_active(0)

        def on_entry_activate(entry):
            button = self.action_area.get_children()[0]
            button.clicked()

        Dialog.__init__(self, 'Connect to a Game')
        self.games = games
        
        hbox = gtk.HBox(False, 1)
        label_box = gtk.VBox(True, 1)
        other_box = gtk.VBox(True, 1) # combo boxes and 2 entries
        label_box.pack_start(gtk.Label('Session: '), False, False, 1)
        self.session_combo_box = gtk.combo_box_new_text()
        for session in sessions:
            self.session_combo_box.append_text(session)
        self.session_combo_box.connect('changed',
                                       on_session_combo_box_changed)
        other_box.pack_start(self.session_combo_box, True, True, 1)
        label_box.pack_start(gtk.Label('Name: '), False, False, 1)
        self.name_combo_box = gtk.combo_box_new_text()
        self.session_combo_box.set_active(0)
        other_box.pack_start(self.name_combo_box, True, True, 1)
        label_box.pack_start(gtk.Label('Password: '), False, False, 1)
        self.passwd_entry = gtk.Entry()
        self.passwd_entry.connect('activate', on_entry_activate)
        self.passwd_entry.set_visibility(False)
        other_box.pack_start(self.passwd_entry, True, True, 1)
        hbox.pack_start(label_box, True, True, 1)
        hbox.pack_start(other_box, True, True, 1)
        self.vbox.pack_start(hbox, False, False, 1)
        self.show_all()


    ## get_session_name ##

    def get_session_name(self):
        '''get_session_name()

Return the session name.
'''
        return self.session_combo_box.get_active_text()


    ## get_login ##

    def get_login(self):
        '''get_login()

Return the login name.
'''
        return self.name_combo_box.get_active_text()


    ## get_passwd ##

    def get_passwd(self):
        '''get_passwd()

Return the password.
'''
        return self.passwd_entry.get_text()


# NewSiteDialog #

class NewSiteDialog(Dialog):
    '''NewSiteDialog(Dialog)

Dialog used to create a new Oto Site.
'''
    def __init__(self):
        def on_entry_activate(entry):
            button = self.action_area.get_children()[0]
            button.clicked()

        Dialog.__init__(self, 'Create an Oto Site')
        hbox = gtk.HBox(False, 1)
        label_box = gtk.VBox(True, 1)
        other_box = gtk.VBox(True, 1)
        label_box.pack_start(gtk.Label('Name: '), False, False, 1)
        self.name_entry = gtk.Entry()
        self.name_entry.connect('activate', on_entry_activate)
        other_box.pack_start(self.name_entry, True, True, 1)
        label_box.pack_start(gtk.Label('Host: '), False, False, 1)
        self.host_entry = gtk.Entry()
        self.host_entry.connect('activate', on_entry_activate)
        other_box.pack_start(self.host_entry, True, True, 1)
        hbox.pack_start(label_box, True, True, 1)
        hbox.pack_start(other_box, True, True, 1)
        self.vbox.pack_start(hbox, False, False, 1)
        self.show_all()

    def get_name(self):
        return self.name_entry.get_text()

    def get_host(self):
        return self.host_entry.get_text()

# DeleteSiteDialog #

class DeleteSiteDialog(Dialog):
    '''DeleteSiteDialog(site_names)

Dialog used to choose a site to delete.
'''
    def __init__(self, site_names):
        Dialog.__init__(self, 'Delete an Oto Site')
        hbox = gtk.HBox(False, 1)
        label_box = gtk.VBox(True, 1)
        other_box = gtk.VBox(True, 1)
        label_box.pack_start(gtk.Label('Site: '), False, False, 1)
        self.site_combo_box = gtk.combo_box_new_text()
        for site in site_names:
            self.site_combo_box.append_text(site)
        self.site_combo_box.set_active(0)
        other_box.pack_start(self.site_combo_box, True, True, 1)
        hbox.pack_start(label_box, True, True, 1)
        hbox.pack_start(other_box, True, True, 1)
        self.vbox.pack_start(hbox, False, False, 1)
        self.show_all()

    def get_name(self):
        return self.site_combo_box.get_active_text()

# ConfirmationDialog #

class ConfirmationDialog(Dialog):
    '''ConfirmationDialog(title, message)

Display a message to the user in a dialog.
'''
    def __init__(self, title, message):
        buttons = (gtk.STOCK_NO, gtk.RESPONSE_NO,
                   gtk.STOCK_YES, gtk.RESPONSE_YES)
        Dialog.__init__(self, title, buttons)
        icon = self.render_icon(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_DIALOG)
        self.set_icon(icon)
        hbox = gtk.HBox()
        image = gtk.Image()
        image.set_from_stock(gtk.STOCK_DIALOG_QUESTION, gtk.ICON_SIZE_DIALOG)
        hbox.pack_start(image, False, False, 1)
        hbox.pack_start(gtk.Label(message), False, False, 1)
        self.vbox.pack_start(hbox, False, False, 1)
        self.show_all()
